/*
 * Professional Android, 4th Edition
 * Reto Meier and Ian Lake
 * Copyright 2018 John Wiley Wiley & Sons, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.professionalandroid.apps.earthquake;

import android.app.Application;
import android.app.SearchManager;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.Transformations;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

/**
 * 10.11 add
 */
public class EarthquakeSearchResultActivity extends AppCompatActivity {

  private ArrayList<Earthquake> mEarthquakes = new ArrayList< >();
  private EarthquakeRecyclerViewAdapter mEarthquakeAdapter = new EarthquakeRecyclerViewAdapter(mEarthquakes);
  /**
   * 10.15.1一个存储当前搜索查询的MutableLiveData对象
   */
  private MutableLiveData<String> searchQuery;
    /**
     * 10.16.1 搜索结果的Earthquake数据集
     */
  private LiveData<List<Earthquake>> searchResults;
  /**
   * 10.24.1 该变量将存储所选的搜索建议的ID
   */
  private MutableLiveData<String> selectedSearchSuggestionId;
  /**
   * 已选择的搜索建议Earthquake对象
   */
  private LiveData<Earthquake> selectedSearchSuggestion;

  /**
   * 10.13   将EarthquakeRecyclerViewAdapter用于此RecyclerView
   */
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_earthquake_search_result);

    RecyclerView recyclerView = findViewById(R.id.search_result_list);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(mEarthquakeAdapter);

    // 10.15.1 初始化搜索查询活动数据。Initialize the search query Live Data.
    searchQuery = new MutableLiveData<>();
    searchQuery.setValue(null);

    // Link the search query Live Data to the search results Live Data.
    // Configure Switch Map such that a change in the search query
    // updates the search results by querying the database.
    // 将search query链接到搜索结果的Live Data。
    //配置switchMap，以便在搜索查询中进行更改
    //通过查询数据库更新搜索结果。
    //10.16.2 Transformations.switchMap方法根据LiveData中的更改自动修改另一个LiveData的底层数据
    //应用switchMap监控searchQuery实时数据，在监控更改时，通过更新后的搜索词查询数据库并更新searchResults实时数据
    searchResults = Transformations.switchMap(searchQuery,
      query -> EarthquakeDatabaseAccessor
                 .getInstance(getApplicationContext())
                 .earthquakeDAO()
                 .searchEarthquakes("%" + query + "%"));

    // 10.16.3 观察searchResults实时数据的变化。 Observe changes to the search results Live Data.
    searchResults.observe(EarthquakeSearchResultActivity.this, searchQueryResultObserver);

    //10.25.1 初始化所选搜索建议Id实时数据。 Initialize the selected search suggestion Id Live Data.
    selectedSearchSuggestionId = new MutableLiveData<>();
    selectedSearchSuggestionId.setValue(null);

    // Link the selected search suggestion ID Live Data to the
    // selected search suggestion Live Data.
    // Configure Switch Map such that a change in the ID of the
    // selected search suggestion, updates the Live Data that
    // returns the corresponding Earthquake by querying the database.
    // 10.25.2 将selectedSearchSuggestionId 链接到 selectedSearchSuggestion实时数据。
    // 配置 Switch Map 以便更改 selected search suggestion ID
    // 通过查询数据库返回对应的 Earthquake。
    selectedSearchSuggestion =
      Transformations.switchMap(selectedSearchSuggestionId,
        id -> EarthquakeDatabaseAccessor
                .getInstance(getApplicationContext())
                .earthquakeDAO()
                .getEarthquake(id));

    // 10.25.3 如果 Activity 是由搜索建议启动的  If the Activity was launched by a search suggestion
    if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
      selectedSearchSuggestion.observe(this,selectedSearchSuggestionObserver);
      setSelectedSearchSuggestion(getIntent().getData());
    }
    else {
      // If the Activity was launched from a search query,
      // extract the search query term and update the search query
      // Live Data.
      //10.16.4  如果活动是从搜索查询启动的，
      //提取搜索查询词并更新searchQuery 实时数据
      String query = getIntent().getStringExtra(SearchManager.QUERY);
      setSearchQuery(query);
    }
  }

  /**
   * 10.17  如果接收到新的搜索请求，那么重写此方法以更新搜索查询
   * @param intent
   */
  @Override
  protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    // If the search Activity exists, and another search
    // is performed, set the launch Intent to the newly
    // received search Intent.
    //如果该搜索Activity存在，并且另一个搜索已经执行
    //则设置启动Intent为新接收的search Intent
    setIntent(intent);
//10.26
    if (Intent.ACTION_VIEW.equals(getIntent().getAction())) {
      // 更新所选搜索建议Id Update the selected search suggestion Id.
      setSelectedSearchSuggestion(getIntent().getData());
    }
    else {
      //10.17.2  提取搜索查询并更新searchQuery实时数据。Extract the search query and update the searchQuery Live Data.
      String query = getIntent().getStringExtra(SearchManager.QUERY);
      setSearchQuery(query);
    }
  }

  /**
   * // 10.15.2 一个修改查询条件的方法
   * @param query 修改的查询语句
   */
  private void setSearchQuery(String query) {
    searchQuery.setValue(query);
  }

  /**
   * 10.15.3 添加一个新的 Live Data Observer ，它将更新RecyclerView中显示的list
   */
  private final Observer<List<Earthquake>> searchQueryResultObserver
    = updatedEarthquakes -> {
    // 使用更新的搜索查询结果更新UI。 Update the UI with the updated search query results.
    mEarthquakes.clear();

    if (updatedEarthquakes != null)
      mEarthquakes.addAll(updatedEarthquakes);

    mEarthquakeAdapter.notifyDataSetChanged();
  };

  /**
   * 10.24.2 该方法从Content Provider URI中提取的地震ID修改 selectedSearchSuggestionId
   */
  private void setSelectedSearchSuggestion(Uri dataString) {
    String id = dataString.getPathSegments().get(1);
    selectedSearchSuggestionId.setValue(id);
  }

  /**
   * 10.24.3 从所选搜索建议中提取详细信息设置搜索查询项
   */
  final Observer<Earthquake> selectedSearchSuggestionObserver
    = selectedSearchSuggestion -> {
    //更新搜索查询以匹配选定的搜索建议。 Update the search query to match the selected search suggestion.
    if (selectedSearchSuggestion != null) {
      setSearchQuery(selectedSearchSuggestion.getDetails());
    }
  };

//  final Observer<Earthquake> selectedSearchSuggestionObserver
//          = new Observer<Earthquake>() {
//    @Override
//    public void onChanged(@Nullable Earthquake selectedSearchSuggestion) {
//      //更新搜索查询以匹配选定的搜索建议。 Update the search query to match the selected search suggestion.
//      if (selectedSearchSuggestion != null) {
//        EarthquakeSearchResultActivity.this.setSearchQuery(selectedSearchSuggestion.getDetails());
//      }
//    }
//  };
}